home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 6 / MacMania 6.toast / / Tools&Utilities / TouchMe 1.2□ / touchMe 1.2 Folder / touchMe source codes / CW11 PP source / source / Common Lib / UFileTools.cp < prev    next >
Encoding:
Text File  |  1997-04-25  |  13.7 KB  |  554 lines  |  [TEXT/CWIE]

  1. // ==================================================
  2. //    UFileTools.cp
  3. //    Copyright (C) 1994-1997 Mizutori Tetsuya
  4. //    March 5, 1997
  5. // ==================================================
  6. //    All documents are pretty-printed in 10-point Geneva font.
  7.  
  8. #include <Files.h>
  9. #include <Processes.h>
  10. #include <Types.h>
  11. #include <LowMem.h>
  12.  
  13. #include "UFileTools.h"
  14. #include <UEnvironment.h>
  15.  
  16.  
  17. // ==================================================
  18. //        • Constructors
  19. // ==================================================
  20.  
  21. // --------------------------------------------------
  22. //        • UFileTools()
  23. // --------------------------------------------------
  24.  
  25. UFileTools::UFileTools()
  26. {
  27. }
  28.  
  29.  
  30. // --------------------------------------------------
  31. //        • ~UFileTools()
  32. // --------------------------------------------------
  33.  
  34. UFileTools::~UFileTools()
  35. {
  36. }
  37.  
  38.  
  39. // ==================================================
  40. //    Member functions (Get and Set the date time stamp)
  41. // ==================================================
  42.  
  43. // --------------------------------------------------
  44. //        • GetFSSpecDateTime
  45. // --------------------------------------------------
  46. // Get the creation/modification date time of the given FSSpec.
  47.  
  48. OSErr
  49. UFileTools::GetFSSpecDateTime(
  50.     FSSpec &        inFSSpec,
  51.     unsigned long &    outCreationDate,
  52.     unsigned long &    outModificationDate )
  53. {
  54.     OSErr    err;
  55.  
  56.     if ( GetFSSpecType( inFSSpec ) == fileType_File ) {
  57.         err = GetFileDateTime( inFSSpec, outCreationDate, outModificationDate );
  58.     } else {
  59.         err = GetFolderDateTime( inFSSpec, outCreationDate, outModificationDate );
  60.     }
  61.  
  62.     return err;
  63. }
  64.  
  65.  
  66. // --------------------------------------------------
  67. //        • SetFSSpecDateTime
  68. // --------------------------------------------------
  69. // Set the creation/modification date time of the given FSSpec.
  70.  
  71. OSErr
  72. UFileTools::SetFSSpecDateTime(
  73.     FSSpec &        inFSSpec,
  74.     unsigned long    inCreationDate,
  75.     unsigned long    inModificationDate )
  76. {
  77.     OSErr    err;
  78.  
  79.     if ( GetFSSpecType( inFSSpec ) == fileType_File ) {
  80.         err = SetFileDateTime( inFSSpec, inCreationDate, inModificationDate );
  81.     } else {
  82.         err = SetFolderDateTime( inFSSpec, inCreationDate, inModificationDate );
  83.     }
  84.  
  85.     TouchDir( inFSSpec.vRefNum, inFSSpec.parID );
  86.     ::FlushVol( NULL, inFSSpec.vRefNum );
  87.  
  88.     return err;
  89. }
  90.  
  91.  
  92. // --------------------------------------------------
  93. //        • GetFileDateTime
  94. // --------------------------------------------------
  95.  
  96. OSErr
  97. UFileTools::GetFileDateTime(
  98.     FSSpec &        inFSSpec,
  99.     unsigned long &    outCreationDate,
  100.     unsigned long &    outModificationDate )
  101. {
  102.     OSErr        err;
  103.     CInfoPBRec    paramBlock;
  104.  
  105.     paramBlock.hFileInfo.ioNamePtr    = inFSSpec.name;
  106.     paramBlock.hFileInfo.ioVRefNum    = inFSSpec.vRefNum;
  107.     paramBlock.hFileInfo.ioDirID    = inFSSpec.parID;
  108.     paramBlock.hFileInfo.ioFDirIndex    = 0;
  109.  
  110.     err = ::PBGetCatInfoSync( ¶mBlock );
  111.     if ( err != noErr ) return err;
  112.  
  113.     outCreationDate        = paramBlock.hFileInfo.ioFlCrDat;
  114.     outModificationDate    = paramBlock.hFileInfo.ioFlMdDat;
  115.  
  116.     return err;
  117. }
  118.  
  119.  
  120. // --------------------------------------------------
  121. //        • SetFileDateTime
  122. // --------------------------------------------------
  123.  
  124. OSErr
  125. UFileTools::SetFileDateTime(
  126.     FSSpec &        inFSSpec,
  127.     unsigned long    inCreationDate,
  128.     unsigned long    inModificationDate )
  129. {
  130.     OSErr        err;
  131.     CInfoPBRec    paramBlock;
  132.  
  133.     paramBlock.hFileInfo.ioNamePtr    = inFSSpec.name;
  134.     paramBlock.hFileInfo.ioVRefNum    = inFSSpec.vRefNum;
  135.     paramBlock.hFileInfo.ioDirID    = inFSSpec.parID;
  136.     paramBlock.hFileInfo.ioFDirIndex    = 0;
  137.  
  138.     err = ::PBGetCatInfoSync( ¶mBlock );
  139.     if ( err != noErr ) return err;
  140.  
  141.     paramBlock.hFileInfo.ioNamePtr    = inFSSpec.name;
  142.     paramBlock.hFileInfo.ioVRefNum    = inFSSpec.vRefNum;
  143.     paramBlock.hFileInfo.ioDirID    = inFSSpec.parID;
  144.     if ( inCreationDate != 0 )        paramBlock.hFileInfo.ioFlCrDat    = inCreationDate;
  145.     if ( inModificationDate != 0 )    paramBlock.hFileInfo.ioFlMdDat    = inModificationDate;
  146.  
  147.     err = ::PBSetCatInfoSync( ¶mBlock );
  148.     if ( err != noErr ) return err;
  149.  
  150. //    TouchDir( inFSSpec.vRefNum, inFSSpec.parID );
  151. //    ::PBFlushFileSync( (ParmBlkPtr) ¶mBlock );
  152.  
  153.     return err;
  154. }
  155.  
  156.  
  157. // --------------------------------------------------
  158. //        • GetFolderDateTime
  159. // --------------------------------------------------
  160.  
  161. OSErr
  162. UFileTools::GetFolderDateTime(
  163.     FSSpec &        inFSSpec,
  164.     unsigned long &    outCreationDate,
  165.     unsigned long &    outModificationDate )
  166. {
  167.     OSErr        err;
  168.     CInfoPBRec    paramBlock;
  169.  
  170.     paramBlock.dirInfo.ioNamePtr    = inFSSpec.name;
  171.     paramBlock.dirInfo.ioVRefNum    = inFSSpec.vRefNum;
  172.     paramBlock.dirInfo.ioDrDirID    = inFSSpec.parID;
  173.     paramBlock.dirInfo.ioFDirIndex    = 0;
  174.  
  175.     err = ::PBGetCatInfoSync( ¶mBlock );
  176.     if ( err != noErr ) return err;
  177.  
  178.     outCreationDate        = paramBlock.dirInfo.ioDrCrDat;
  179.     outModificationDate    = paramBlock.dirInfo.ioDrMdDat;
  180.  
  181.     return err;
  182. }
  183.  
  184.  
  185. // --------------------------------------------------
  186. //        • SetFolderDateTime
  187. // --------------------------------------------------
  188.  
  189. OSErr
  190. UFileTools::SetFolderDateTime(
  191.     FSSpec &        inFSSpec,
  192.     unsigned long    inCreationDate,
  193.     unsigned long    inModificationDate )
  194. {
  195.     OSErr        err;
  196.     CInfoPBRec    paramBlock;
  197.  
  198.     paramBlock.dirInfo.ioNamePtr    = inFSSpec.name;
  199.     paramBlock.dirInfo.ioVRefNum    = inFSSpec.vRefNum;
  200.     paramBlock.dirInfo.ioDrDirID    = inFSSpec.parID;
  201.     paramBlock.dirInfo.ioFDirIndex    = 0;
  202.  
  203.     err = ::PBGetCatInfoSync( ¶mBlock );
  204.     if ( err != noErr ) return err;
  205.  
  206.     paramBlock.dirInfo.ioNamePtr    = inFSSpec.name;
  207.     paramBlock.dirInfo.ioVRefNum    = inFSSpec.vRefNum;
  208.     paramBlock.dirInfo.ioDrDirID    = inFSSpec.parID;
  209.     if ( inCreationDate != 0 )        paramBlock.dirInfo.ioDrCrDat    = inCreationDate;
  210.     if ( inModificationDate != 0 )    paramBlock.dirInfo.ioDrMdDat    = inModificationDate;
  211.  
  212.     err = ::PBSetCatInfoSync( ¶mBlock );
  213.     if ( err != noErr ) return err;
  214.  
  215. //    TouchDir( inFSSpec.vRefNum, inFSSpec.parID );
  216. //    ::PBFlushVolSync( (ParmBlkPtr) ¶mBlock );
  217.  
  218.     return err;
  219. }
  220.  
  221.  
  222. // ==================================================
  223. //    Member functions (Finder's info)
  224. // ==================================================
  225.  
  226. // --------------------------------------------------
  227. //        • TouchDir
  228. // --------------------------------------------------
  229. // Update the finder's folder status.
  230.  
  231. OSErr
  232. UFileTools::TouchDir(
  233.     short        inVRefNum,
  234.     long        inDirID )
  235. {
  236.     CInfoPBRec    paramBlock;
  237.     Str255        theFilename;
  238.     OSErr        err;
  239.  
  240.     paramBlock.dirInfo.ioDrDirID    = inDirID;
  241.     paramBlock.dirInfo.ioVRefNum    = inVRefNum;
  242.     paramBlock.dirInfo.ioNamePtr    = theFilename;
  243.     paramBlock.dirInfo.ioFDirIndex    = -1;
  244.  
  245.     err = ::PBGetCatInfoSync( ¶mBlock );
  246.  
  247.     if ( err == noErr ) {
  248.         paramBlock.dirInfo.ioCompletion    = 0;
  249.         paramBlock.dirInfo.ioDrDirID    = paramBlock.dirInfo.ioDrParID;
  250.         paramBlock.dirInfo.ioFDirIndex    = 0;
  251.         ::GetDateTime( ¶mBlock.dirInfo.ioDrMdDat );
  252.  
  253.         err = ::PBSetCatInfoSync( ¶mBlock );
  254.     }
  255.  
  256.     return err;
  257. }
  258.  
  259.  
  260. // --------------------------------------------------
  261. //        • GetFSSpecType
  262. // --------------------------------------------------
  263. // Test the file type of a particular file
  264.  
  265. EFileType
  266. UFileTools::GetFSSpecType(
  267.     FSSpec &        inFSSpec )
  268. {
  269.     OSErr        err;
  270.     EFileType        theFileType;
  271.  
  272.     if ( (inFSSpec.parID) == fsRtParID ) {
  273.  
  274.         theFileType = fileType_Volume;
  275.  
  276.     } else {
  277.  
  278.         CInfoPBRec    paramBlock;
  279.         paramBlock.hFileInfo.ioFDirIndex    = 0;
  280.         paramBlock.hFileInfo.ioNamePtr    = inFSSpec.name;
  281.         paramBlock.hFileInfo.ioVRefNum    = inFSSpec.vRefNum;
  282.         paramBlock.hFileInfo.ioDirID    = inFSSpec.parID;
  283.  
  284.         err = ::PBGetCatInfoSync( ¶mBlock );
  285.  
  286.         if ( err == noErr ) {
  287.             if ( (paramBlock.hFileInfo.ioFlAttrib & 0x10) != 0 )
  288.                 theFileType = fileType_Folder;
  289.             else
  290.                 theFileType = fileType_File;
  291.         } else {
  292.                 theFileType = fileType_Unknown;
  293.         }
  294.  
  295.     }
  296.  
  297.     return theFileType;
  298. }
  299.  
  300.  
  301. // --------------------------------------------------
  302. //        • QueryFile
  303. // --------------------------------------------------
  304. //    input:
  305. //        inFSSpec            ;; a FSSpec for an existing file or directory.
  306. //    output:
  307. //        outFileType        ;; file type { fileType_File ; fileType_Folder }.
  308. //        outFileID            ;; the id of the file or directory.
  309. //    return err if no such a file or directory exists.
  310.  
  311. OSErr
  312. UFileTools::QueryFile(
  313.     FSSpec &        inFSSpec,
  314.     EFileType &    outFileType,
  315.     long &        outFileID )
  316. {
  317.     OSErr        err;
  318.     CInfoPBRec    paramBlock;
  319.  
  320.     paramBlock.hFileInfo.ioFDirIndex    = 0;
  321.     paramBlock.hFileInfo.ioNamePtr    = inFSSpec.name;
  322.     paramBlock.hFileInfo.ioVRefNum    = inFSSpec.vRefNum;
  323.     paramBlock.hFileInfo.ioDirID    = inFSSpec.parID;
  324.  
  325. //    paramBlock.dirInfo.ioFDirIndex    = 0;
  326. //    paramBlock.dirInfo.ioNamePtr    = inFSSpec.name;
  327. //    paramBlock.dirInfo.ioVRefNum    = inFSSpec.vRefNum;
  328. //    paramBlock.dirInfo.ioDrDirID    = inFSSpec.parID;
  329.  
  330.     err = ::PBGetCatInfoSync( ¶mBlock );
  331.     if ( err != noErr ) return err;
  332.  
  333.     // Determine the file type; a file or a directory.
  334.     if ( (paramBlock.hFileInfo.ioFlAttrib & 0x10) != 0 ) {
  335.         outFileType = fileType_Folder;
  336.         outFileID = paramBlock.dirInfo.ioDrDirID;
  337.     } else {
  338.         outFileType = fileType_File;
  339.         outFileID = paramBlock.hFileInfo.ioDirID;
  340.     }
  341.  
  342.     return err;
  343. }
  344.  
  345.  
  346. // --------------------------------------------------
  347. //        • SearchDirectory
  348. // --------------------------------------------------
  349. // Search a particure directory for the files in it.
  350. // Returns the file spec for the particular index number with noErr.
  351. // Otherwise returns with no-noErr code if exist no more files.
  352. // Root directory number is 'fsRtDirID(2)'.
  353. // Parent directory number of root is 'fsRtParID(1)'.
  354. // Example. FSSpec of directory path = "tmp:abc:" is {.vRefNum=?,.parID=2, .name="abc"}
  355.  
  356. OSErr
  357. UFileTools::SearchDirectory(
  358.     long            inIndex,        // begins with one.
  359.     FSSpec &        inDirSpec,        // root directory
  360.     FSSpec &        outFSSpec,
  361.     EFileType &    outFileType )
  362. {
  363.     OSErr        err;
  364.  
  365.     // Check whether the inDirSpec is a directory. If it is, then get its directory ID.
  366.     EFileType        fileType;
  367.     long            dirID;
  368.     err = QueryFile( inDirSpec, fileType, dirID );
  369.     if ( err != noErr ) return err;
  370.     if ( fileType != fileType_Folder ) return fnfErr;
  371.  
  372.     err = SearchDirectory( inIndex, inDirSpec.vRefNum, dirID, outFSSpec, outFileType );
  373.  
  374.     return err;
  375. }
  376.  
  377.  
  378. OSErr
  379. UFileTools::SearchDirectory(
  380.     long            inIndex,        // begins with one.
  381.     short            inVRefNum,
  382.     long            inDirID,
  383.     FSSpec &        outFSSpec,
  384.     EFileType &    outFileType )
  385. {
  386.     OSErr        err = fnfErr;
  387.     if ( inIndex <= 0 ) return err;    // index must begin with one.
  388.  
  389.     // Set outFSSpec that this is in the same directory.
  390.     outFSSpec.vRefNum = inVRefNum;
  391.     outFSSpec.parID = inDirID;
  392.  
  393.     // Determine the file or directory whose index number is inIndex in the directory dirID.
  394.     CInfoPBRec    paramBlock;
  395.     paramBlock.hFileInfo.ioFDirIndex    = inIndex;
  396.     paramBlock.hFileInfo.ioNamePtr    = outFSSpec.name;
  397.     paramBlock.hFileInfo.ioVRefNum    = outFSSpec.vRefNum;
  398.     paramBlock.hFileInfo.ioDirID    = outFSSpec.parID;
  399.  
  400.     err = ::PBGetCatInfoSync( ¶mBlock );
  401.     if ( err != noErr ) return err;
  402.  
  403.     // Determine the file type; a file or a directory.
  404.     if ( (paramBlock.hFileInfo.ioFlAttrib & 0x10) != 0 ) {
  405.         outFileType = fileType_Folder;
  406.     //    outFileID = paramBlock.dirInfo.ioDrDirID;
  407.     } else {
  408.         outFileType = fileType_File;
  409.     //    outFileID = paramBlock.hFileInfo.ioDirID;
  410.     }
  411.  
  412.     return err;
  413. }
  414.  
  415.  
  416. // --------------------------------------------------
  417. //        • GetFullPathname
  418. // --------------------------------------------------
  419. // Get the full pathname of a particular file.
  420.  
  421. OSErr
  422. UFileTools::GetFullPathname(
  423.     const FSSpec &    inFSSpec,
  424.     Str255        outPathname,
  425.     Boolean        inAddFilename )        //    = false
  426. {
  427.     OSErr        err = noErr;
  428.  
  429.     // Let's start with the file name.
  430.     if ( inAddFilename ) {
  431.         PStrCopy( outPathname, inFSSpec.name );
  432.     } else {
  433.         PStrCopy( outPathname, "\p" );
  434.     }
  435.  
  436.     CInfoPBRec    paramBlock;
  437.     Str255        theDirName;
  438.  
  439.     // Next, get the parent directory name, and insert it to the pathname.
  440.     paramBlock.dirInfo.ioNamePtr = theDirName;
  441.     paramBlock.dirInfo.ioDrParID = inFSSpec.parID;
  442.  
  443.     do {
  444.         paramBlock.dirInfo.ioVRefNum    = inFSSpec.vRefNum;
  445.         paramBlock.dirInfo.ioFDirIndex    = -1;
  446.         paramBlock.dirInfo.ioDrDirID    = paramBlock.dirInfo.ioDrParID;
  447.  
  448.         err = ::PBGetCatInfoSync( ¶mBlock );
  449.         if ( err != noErr ) break;
  450.  
  451.         PStrAppend( theDirName, "\p:" );
  452.         PStrAppend( theDirName, outPathname );
  453.         PStrCopy( outPathname, theDirName );
  454.  
  455.     } while ( paramBlock.dirInfo.ioDrDirID != fsRtDirID );
  456.  
  457.     return err;
  458. }
  459.  
  460.  
  461. // --------------------------------------------------
  462. //        • GetCurrentApplicationFile
  463. // --------------------------------------------------
  464. // Get the file spec of the current application process.
  465.  
  466. OSErr
  467. UFileTools::GetCurrentApplicationFile(
  468.     FSSpec &        outFSSpec )
  469. {
  470.     OSErr    err;
  471.  
  472.     ProcessSerialNumber        theProcessID;
  473.     err = ::GetCurrentProcess( &theProcessID );
  474.     if ( err != noErr ) return err;
  475.  
  476. //    Str63            processName;
  477.     ProcessInfoRec        theProcessInfo;
  478.     theProcessInfo.processName = NULL;    // processName;        // We don't need process name, here.
  479.     theProcessInfo.processAppSpec = &outFSSpec;            // Allocate the storage for FSSpec.
  480.     err = ::GetProcessInformation( &theProcessID, &theProcessInfo );
  481.     if ( err != noErr ) return err;
  482.  
  483.     return err;
  484. }
  485.  
  486.  
  487. // ==================================================
  488. //    Common functions (handling p-strings)
  489. // ==================================================
  490.  
  491. const long        kMaxString    = 255;
  492.  
  493. // --------------------------------------------------
  494. //        • PStrCopy
  495. // --------------------------------------------------
  496.  
  497. void
  498. UFileTools::PStrCopy(
  499.     Str255            dstP,
  500.     const Str255        srcP )
  501. {
  502.     dstP[0] =  srcP[0];
  503.     ::BlockMoveData( &srcP[1], &dstP[1], dstP[0] );
  504. }
  505.  
  506.  
  507. void
  508. UFileTools::PStrCopy(
  509.     Str255            dstP,
  510.     const unsigned char *    srcP,
  511.     const long            length )
  512. {
  513.     long        k = length;
  514.     dstP[0] = ( k > kMaxString ? kMaxString : k );
  515.  
  516.     ::BlockMoveData( srcP, &dstP[1], dstP[0] );
  517. }
  518.  
  519.  
  520. // --------------------------------------------------
  521. //        • PStrAppend
  522. // --------------------------------------------------
  523.  
  524. void
  525. UFileTools::PStrAppend(
  526.     Str255            dstP,
  527.     const Str255        srcP )
  528. {
  529.     long        n = dstP[0];
  530.  
  531.     long        k = (long) dstP[0] + (long) srcP[0];
  532.     dstP[0] = ( k > kMaxString ? kMaxString : k );
  533.  
  534.     ::BlockMoveData( &srcP[1], &dstP[1+n], dstP[0]-n );
  535. }
  536.  
  537.  
  538. void
  539. UFileTools::PStrAppend(
  540.     Str255            dstP,
  541.     const unsigned char *    srcP,
  542.     const long            length )
  543. {
  544.     long        n = dstP[0];
  545.  
  546.     long        k = (long) dstP[0] + length;
  547.     dstP[0] = ( k > kMaxString ? kMaxString : k );
  548.  
  549.     ::BlockMoveData( srcP, &dstP[1+n], dstP[0]-n );
  550. }
  551.  
  552.  
  553. // end of program
  554.